package com.exigen.training.domain;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.imageio.ImageIO;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;

import com.exigen.training.UserEntity;
import com.exigen.training.dao.UserDAO;
import com.exigen.training.services.UserService;

public class User {

	private UserService userService;
	
	private String userFirstName;
	private String userLastName;
	private String userPersonalNumber;
	private String userLogin;
	private String userPassword;
	private byte[] userProfileImage;
	private String imageLink;
	
	private static final int IMG_WIDTH = 250;
	private static final int IMG_HEIGHT = 250;

	private StreamedContent image;
	public PasswordEncoder crypto = new Md5PasswordEncoder();

	public void addNewUser(ActionEvent event) {

		UserEntity user = new UserEntity();
		user.setUserFirstName(userFirstName);
		user.setUserLastName(userFirstName);
		user.setUserLogin(userLogin);
		user.setUserPassword(userPassword);
		user.setUserPersonalNumber(userPersonalNumber);

		// add image to profile and resize
		File file = new File("C:\\Users\\gdudelis\\Desktop\\index.jpg");
		try {
			BufferedImage originalImage = ImageIO.read(file);
			int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
			BufferedImage resizeImageJpg = resizeImage(originalImage, type);
			ImageIO.write(resizeImageJpg, "jpg", new File("C:\\Users\\gdudelis\\Desktop\\index.jpg")); 
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		byte[] bImage = new byte[(int) file.length()];

		try {
			FileInputStream fileInputStream = new FileInputStream(file);
			fileInputStream.read(bImage);
			fileInputStream.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

		userProfileImage = bImage;
		user.setUserProfileImage(userProfileImage);

		try // try to add user
		{
			userService.createUserIfNotExist(user);

			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("User Added!"));
		}

		catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(e.getMessage()));
		}
	}

	// user authentication
	@SuppressWarnings("null")
	public void userAuthentication(ActionEvent event) {
		String message = "";
		UserEntity user = null;

		try {
			user = (UserEntity) userService.getUserByUserName(userLogin);
			userFirstName = user.getUserFirstName();
			userLastName = user.getUserLastName();
			userPersonalNumber = user.getUserPersonalNumber();
			userProfileImage = user.getUserProfileImage();

			InputStream inputStream = new ByteArrayInputStream(userProfileImage);
			image = new DefaultStreamedContent(inputStream, "image/jpg");
		}

		catch (Exception e) {
			message = "Fatal error!";
		}

		if (user != null) {

			// loged
			if (userPassword.endsWith(user.getUserPassword())) {
				ExternalContext context = FacesContext.getCurrentInstance()
						.getExternalContext();
				try {
					context.redirect("profile");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			else {
				message = "Login or password incorrect!";
			}
		}

		else {
			message = "Login or password incorrect!";
		}

		FacesContext.getCurrentInstance().addMessage(null,
				new FacesMessage(message));
	}

	public void goToNewUser(ActionEvent event) {
		ExternalContext context = FacesContext.getCurrentInstance()
				.getExternalContext();
		try {
			context.redirect("newUser");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	 @SuppressWarnings("unused")
	private static BufferedImage resizeImage(BufferedImage originalImage, int type){
			BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
			Graphics2D g = resizedImage.createGraphics();
			g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
			g.dispose();
		 
			return resizedImage;
		    }

	public void handleFileUpload(FileUploadEvent event) {
		FacesMessage msg = new FacesMessage("Succesful", event.getFile()
				.getFileName() + " is uploaded.");
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public StreamedContent getImage() {
		return image;
	}

	public void setImage(StreamedContent image) {
		this.image = image;
	}

	public byte[] getUserProfileImage() {
		return userProfileImage;
	}

	public void setUserProfileImage(byte[] userProfileImage) {
		this.userProfileImage = userProfileImage;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public String getUserFirstName() {
		return userFirstName;
	}

	public void setUserFirstName(String userFirstName) {
		this.userFirstName = userFirstName;
	}

	public String getUserLastName() {
		return userLastName;
	}

	public void setUserLastName(String userLastName) {
		this.userLastName = userLastName;
	}

	public String getUserPersonalNumber() {
		return userPersonalNumber;
	}

	public void setUserPersonalNumber(String userPersonalNumber) {
		this.userPersonalNumber = userPersonalNumber;
	}

	public String getUserLogin() {
		return userLogin;
	}

	public void setUserLogin(String userLogin) {
		this.userLogin = userLogin;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		// hash
		userPassword = crypto.encodePassword(userPassword, null);
		this.userPassword = userPassword;
	}
}
